package com.sanyou.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sanyou.mapper.FactoryMapper;
import com.sanyou.mapper.UserEquipFactoryMapper;
import com.sanyou.pojo.Equipment;
import com.sanyou.pojo.Factory;
import com.sanyou.pojo.UserEquipFactory;
import com.sanyou.pojo.vo.FactoryVo;
import com.sanyou.service.EquipmentService;
import com.sanyou.service.FactoryService;
import com.sanyou.service.RoleService;
import com.sanyou.utils.PagedResult;
import org.apache.commons.lang3.StringUtils;
import org.n3r.idworker.Sid;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * User: asus
 * Date: 2021/5/26
 * Time: 1:44
 * Version:V1.0
 */
@Service
public class FactoryServiceImpl implements FactoryService {

    @Resource
    private FactoryMapper factoryMapper;

    @Autowired
    private EquipmentService equipmentService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private Sid sid;

    @Resource
    private UserEquipFactoryMapper userEquipFactoryMapper;

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public Factory findByName(String factoryName,String parentId) {
        Example example = new Example(Factory.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("factoryName",factoryName);
        criteria.andEqualTo("deleteMark", 0);

        if(StringUtils.isNotBlank(parentId)){
            criteria.andEqualTo("parentId", parentId);
            criteria.andEqualTo("layer", 2);
        }else{
            criteria.andEqualTo("layer", 1);
        }


        return factoryMapper.selectOneByExample(example);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public Factory findById(String id) {
        Example example = new Example(Factory.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("id",id);

        return factoryMapper.selectOneByExample(example);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void addFactory(Factory factory) {
        String id = sid.nextShort();
        factory.setId(id);
        factory.setCreatetime(new Date());
        factory.setUpdatetime(new Date());
        factory.setDeleteMark((byte)0);

        factoryMapper.insert(factory);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void updateFactoryInfo(Factory factory) {
        Example example = new Example(Factory.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("id",factory.getId());

        factory.setUpdatetime(new Date());
        if(factory.getDeleteMark() != null && factory.getDeleteMark() == 1){
            factory.setDeletetime(new Date());
            if(factory.getLayer() != null && factory.getLayer() == 1){
                Example example2 = new Example(Factory.class);
                Example.Criteria criteria2 = example2.createCriteria();
                criteria2.andEqualTo("parentId",factory.getId());

                Factory factory2 = new Factory();
                factory2.setDeleteMark((byte)1);
                factoryMapper.updateByExampleSelective(factory2,example2);
            }
        }

        factoryMapper.updateByExampleSelective(factory,example);
    }
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public PagedResult query(String query, String userId,Integer page, Integer pageSize) {
        boolean isAdmin = roleService.iSAdminByUserId(userId);
        PageHelper.startPage(page,pageSize);
        List<FactoryVo> factoryList = null;
        if(isAdmin){
            factoryList = factoryMapper.query(null);
        }else {
            factoryList = factoryMapper.queryById(userId);
        }
        int index = (page-1) * pageSize + 1;
        for (FactoryVo factoryVo : factoryList) {
            factoryVo.setIndex(index++);
            Example example = new Example(Factory.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("parentId",factoryVo.getId());
            criteria.andEqualTo("deleteMark",0);
            criteria.andEqualTo("layer",2);
            List<Factory> factoryList1 = factoryMapper.selectByExample(example);
            if(factoryList1 != null && factoryList1.size() > 0){
                factoryVo.setHasChildren(true);
            }else{
                factoryVo.setHasChildren(false);
            }
        }
        PageInfo<FactoryVo> pageList = new PageInfo<>(factoryList);
        PagedResult pagedResult = new PagedResult();
        pagedResult.setPage(page);
        pagedResult.setTotal(pageList.getPages());
        pagedResult.setRows(factoryList);
        pagedResult.setRecords(pageList.getTotal());
        return pagedResult;
    }
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public PagedResult query(String query, Integer page, Integer pageSize) {

        PageHelper.startPage(page,pageSize);
        List<FactoryVo> factoryList = factoryMapper.query(query);

        int index = (page-1) * pageSize + 1;
        for (FactoryVo factoryVo : factoryList) {
            factoryVo.setIndex(index++);

            Example example = new Example(Factory.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("parentId",factoryVo.getId());
            criteria.andEqualTo("deleteMark",0);
            criteria.andEqualTo("layer",2);
            List<Factory> factoryList1 = factoryMapper.selectByExample(example);

            if(factoryList1 != null && factoryList1.size() > 0){
                factoryVo.setHasChildren(true);
            }else{
                factoryVo.setHasChildren(false);
            }
        }

        PageInfo<FactoryVo> pageList = new PageInfo<>(factoryList);

        PagedResult pagedResult = new PagedResult();
        pagedResult.setPage(page);
        pagedResult.setTotal(pageList.getPages());
        pagedResult.setRows(factoryList);
        pagedResult.setRecords(pageList.getTotal());
        return pagedResult;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<Factory> querySubFactory(String parentId) {

        Example example = new Example(Factory.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("parentId",parentId);
        criteria.andEqualTo("deleteMark",0);
        criteria.andEqualTo("layer",2);
        List<Factory> factories = factoryMapper.selectByExample(example);

        return factories;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<Factory> querySubFactoryById(String parentId,String userId){
        if(roleService.iSAdminByUserId(userId)){
            userId = null;
        }
        List<Factory> factories= factoryMapper.querySubFactoryById(parentId,userId);
        return factories;
    }
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<Factory> getAll() {

        Example example = new Example(Factory.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("deleteMark",0);
        criteria.andEqualTo("layer",1);
        List<Factory> factoryList = factoryMapper.selectByExample(example);

        return factoryList;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<Factory> getUserEquipFactory(String userId) {

        Example example = new Example(UserEquipFactory.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId",userId);
        List<UserEquipFactory> userEquipFactories = userEquipFactoryMapper.selectByExample(example);

        if(userEquipFactories == null || userEquipFactories.size() == 0)
            return new ArrayList<>();
        List<String> factoryIds = userEquipFactories.stream().map(t->t.getFactoryId()).collect(Collectors.toList());
        Example example2 = new Example(Factory.class);
        Example.Criteria criteria2 = example2.createCriteria();
        criteria2.andIn("id",factoryIds);
        criteria2.andEqualTo("layer",(byte)2);
        List<Factory> factoryList = factoryMapper.selectByExample(example2);

        return factoryList;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<FactoryVo> getFactoryTree() {
        List<FactoryVo> resultList = new ArrayList<>();

        List<Factory> factoryList = factoryMapper.selectAll();
        List<FactoryVo> factoryVoList = new ArrayList<>();
        for (Factory factory : factoryList) {
            FactoryVo factoryVo = new FactoryVo();
            BeanUtils.copyProperties(factory,factoryVo);
            factoryVo.setLabel(factoryVo.getFactoryName());
            if(factoryVo.getDeleteMark() == 0)
                factoryVoList.add(factoryVo);
        }
        List<FactoryVo> parentFactoryList = factoryVoList.stream().filter(t->t.getLayer() == 1).collect(Collectors.toList());
        List<FactoryVo> subFactoryList = factoryVoList.stream().filter(t -> t.getLayer() == 2).collect(Collectors.toList());

        for (FactoryVo factoryVo : parentFactoryList) {
            List<FactoryVo> children = subFactoryList.stream().filter(t -> factoryVo.getId().equals(t.getParentId())).collect(Collectors.toList());
            factoryVo.setChildren(children);
            resultList.add(factoryVo);
        }


        return resultList;
    }


    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<Factory> getFactory(String userId) {

        List<Factory> factoryList = factoryMapper.getFactory(userId);

        return factoryList;
    }


    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<Factory> getSubFactory(String userId, String factoryId) {

        List<Factory> subFactoryList = factoryMapper.getSubFactory(userId,factoryId);

        return subFactoryList;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void updateAddress(Factory factory) {
        if(factory == null || StringUtils.isBlank(factory.getId())){return;}

        //更新车间地址
        factoryMapper.updateByPrimaryKeySelective(factory);

        //更新车间下属所有设备的地址
        List<Equipment> equipmentList = equipmentService.getEquip(factory.getId());
        for (Equipment equipment:equipmentList) {
            //设置设备地址
            equipment.setEquipAddress(factory.getFactoryAddress());
            equipment.setEquipLat(factory.getFactoryLat());
            equipment.setEquipLng(factory.getFactoryLng());
            //更新设备地址
            equipmentService.updateAddress(equipment);
        }
    }

    @Override
    public List<Factory> getAllSubFactory() {
        return factoryMapper.getAllSubFactory();
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public List<Factory> getSubFactoryById(String factoryId) {
        List<Factory> result = factoryMapper.getSubFactoryById(factoryId);

        if(result == null){
            result = new ArrayList<>();
        }
        return result;
    }

}
